gsk_render_node_unref (node);
}
+gboolean
+gtk_snapshot_get_clip (GtkSnapshot *snapshot,
+ graphene_rect_t *out_clip)
+{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
+
+ if (!current_state->has_clip)
+ return FALSE;
+
+ graphene_rect_offset_r (¤t_state->clip,
+ - current_state->translate_x,
+ - current_state->translate_y,
+ out_clip);
+
+ return TRUE;
+}
+
/**
* gtk_snapshot_clips_rect:
* @snapshot: a #GtkSnapshot
GObjectClass parent_class; /* it's really GdkSnapshotClass, but don't tell anyone! */
};
-GtkSnapshot * gtk_snapshot_new_child (GtkSnapshot *parent,
- const char *name,
- ...) G_GNUC_PRINTF (2, 3);
-void gtk_snapshot_append_node_internal (GtkSnapshot *snapshot,
- GskRenderNode *node);
+GtkSnapshot * gtk_snapshot_new_child (GtkSnapshot *parent,
+ const char *name,
+ ...) G_GNUC_PRINTF (2, 3);
+void gtk_snapshot_append_node_internal (GtkSnapshot *snapshot,
+ GskRenderNode *node);
+gboolean gtk_snapshot_get_clip (GtkSnapshot *snapshot,
+ graphene_rect_t *out_clip);
G_END_DECLS
priv->draw_needed = TRUE;
g_clear_pointer (&priv->render_node, gsk_render_node_unref);
+ priv->render_node_has_clip = FALSE;
gtk_widget_invalidate_paintable_contents (widget);
if (_gtk_widget_get_has_surface (widget) &&
_gtk_widget_get_realized (widget))
{
GtkWidgetPrivate *priv = widget->priv;
graphene_rect_t offset_clip;
+ graphene_rect_t clip;
+ gboolean has_clip;
double opacity;
if (!_gtk_widget_is_drawable (widget))
if (opacity <= 0.0)
return;
- if (priv->draw_needed)
+ has_clip = gtk_snapshot_get_clip (snapshot, &clip);
+
+ if (priv->draw_needed ||
+ (priv->render_node_has_clip && (!has_clip || !graphene_rect_contains_rect (&priv->render_node_clip, &clip))))
{
GskRenderNode *render_node;
+
render_node = gtk_widget_create_render_node (widget, snapshot);
- /* This can happen when nested drawing happens and a widget contains itself */
+ /* This can happen when nested drawing happens and a widget contains itself
+ * or when we replace a clipped area */
g_clear_pointer (&priv->render_node, gsk_render_node_unref);
priv->render_node = render_node;
+ if (has_clip)
+ {
+ priv->render_node_clip = clip;
+ priv->render_node_has_clip = TRUE;
+ }
+ else
+ {
+ priv->render_node_has_clip = FALSE;
+ }
+
priv->draw_needed = FALSE;
}
/* Queue-draw related flags */
guint draw_needed : 1;
+ guint render_node_has_clip : 1;
/* Expand-related flags */
guint need_compute_expand : 1; /* Need to recompute computed_[hv]_expand */
/* The widget's requested sizes */
SizeRequestCache requests;
- /* The render node we draw or %NULL if not yet created. */
+ /* The render node we draw or %NULL if not yet created.*/
GskRenderNode *render_node;
+ /* The clip that existed when the render node was drawn
+ * Ignored when render_node_has_clip == FALSE */
+ graphene_rect_t render_node_clip;
GSList *paintables;